#include "Car.h"
#include <iomanip>
#include <cerrno>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>

// Subject类方法实现（非const）
void Subject::attach(Observer* observer) {
    observers.push_back(observer);
    std::cout << "[订阅通知] 底盘已订阅激光雷达消息" << std::endl;
}

void Subject::detach(Observer* observer) {
    for (auto it = observers.begin(); it != observers.end(); ++it) {
        if (*it == observer) {
            observers.erase(it);
            std::cout << "[订阅通知] 底盘已取消订阅激光雷达消息" << std::endl;
            break;
        }
    }
}

void Subject::notify(const std::string& obstacleStatus) {
    for (auto observer : observers) {
        observer->update(obstacleStatus);
    }
}

// 运算符重载实现
std::ostream& operator<<(std::ostream& os, const Tire& tire) {
    os << tire.getType() << "|";
    os << tire.getSize();
    return os;
}

std::istream& operator>>(std::istream& is, Tire& tire) {
    std::string type, size;
    std::getline(is, type, '|');
    std::getline(is, size);
    tire.setType(type);
    tire.setSize(size);
    return is;
}

std::ostream& operator<<(std::ostream& os, const Chassis& chassis) {
    os << chassis.getId() << "|";
    os << chassis.getModel() << "|";
    os << chassis.getWheelbase() << "|";
    os << chassis.getTrackWidth() << "|";
    os << chassis.getMinGroundClear() << "|";
    os << chassis.getMinTurnRadius() << "|";
    os << chassis.getDriveType() << "|";
    os << chassis.getMaxRange();
    
    for (int i = 0; i < 4; ++i) {
        os << "|" << chassis.getTires(i);
    }
    return os;
}

std::istream& operator>>(std::istream& is, Chassis& chassis) {
    std::string id, model, wheelbase, trackWidth, minGroundClear, minTurnRadius, driveType, maxRange;
    std::getline(is, id, '|');
    std::getline(is, model, '|');
    std::getline(is, wheelbase, '|');
    std::getline(is, trackWidth, '|');
    std::getline(is, minGroundClear, '|');
    std::getline(is, minTurnRadius, '|');
    std::getline(is, driveType, '|');
    std::getline(is, maxRange, '|');
    
    Tire tires[4];
    for (int i = 0; i < 4; ++i) {
        std::string tireStr;
        std::getline(is, tireStr, '|');
        std::istringstream tireIss(tireStr);
        tireIss >> tires[i];
    }
    
    chassis.setId(id);
    chassis.setModel(model);
    chassis.setWheelbase(wheelbase);
    chassis.setTrackWidth(trackWidth);
    chassis.setMinGroundClear(minGroundClear);
    chassis.setMinTurnRadius(minTurnRadius);
    chassis.setDriveType(driveType);
    chassis.setMaxRange(maxRange);
    
    for (int i = 0; i < 4; ++i) {
        chassis.setTires(i, tires[i]);
    }
    
    return is;
}

std::ostream& operator<<(std::ostream& os, const AGXKit& agxKit) {
    os << agxKit.getModel() << "|";
    os << agxKit.getAiPerformance() << "|";
    os << agxKit.getCudaCores() << "|";
    os << agxKit.getTensorCores() << "|";
    os << agxKit.getVram() << "|";
    os << agxKit.getStorage();
    return os;
}

std::istream& operator>>(std::istream& is, AGXKit& agxKit) {
    std::string model, aiPerformance, cudaCores, tensorCores, vram, storage;
    std::getline(is, model, '|');
    std::getline(is, aiPerformance, '|');
    std::getline(is, cudaCores, '|');
    std::getline(is, tensorCores, '|');
    std::getline(is, vram, '|');
    std::getline(is, storage);
    
    agxKit.setModel(model);
    agxKit.setAiPerformance(aiPerformance);
    agxKit.setCudaCores(cudaCores);
    agxKit.setTensorCores(tensorCores);
    agxKit.setVram(vram);
    agxKit.setStorage(storage);
    return is;
}

std::ostream& operator<<(std::ostream& os, const StereoCamera& stereoCam) {
    os << stereoCam.getModel() << "|";
    os << stereoCam.getCamModule() << "|";
    os << stereoCam.getRgbRes() << "|";
    os << stereoCam.getRgbFps() << "|";
    os << stereoCam.getFov() << "|";
    os << stereoCam.getDepthFps();
    return os;
}

std::istream& operator>>(std::istream& is, StereoCamera& stereoCam) {
    std::string model, camModule, rgbRes, rgbFps, fov, depthFps;
    std::getline(is, model, '|');
    std::getline(is, camModule, '|');
    std::getline(is, rgbRes, '|');
    std::getline(is, rgbFps, '|');
    std::getline(is, fov, '|');
    std::getline(is, depthFps);
    
    stereoCam.setModel(model);
    stereoCam.setCamModule(camModule);
    stereoCam.setRgbRes(rgbRes);
    stereoCam.setRgbFps(rgbFps);
    stereoCam.setFov(fov);
    stereoCam.setDepthFps(depthFps);
    return is;
}

std::ostream& operator<<(std::ostream& os, const LiDAR& lidar) {
    os << lidar.getModel() << "|";
    os << lidar.getLines() << "|";
    os << lidar.getTestRange() << "|";
    os << lidar.getPower() << "|";
    os << lidar.getObstacleStatus();
    return os;
}

std::istream& operator>>(std::istream& is, LiDAR& lidar) {
    std::string model, lines, testRange, power, obstacleStatus;
    std::getline(is, model, '|');
    std::getline(is, lines, '|');
    std::getline(is, testRange, '|');
    std::getline(is, power, '|');
    std::getline(is, obstacleStatus);
    
    lidar.setModel(model);
    lidar.setLines(lines);
    lidar.setTestRange(testRange);
    lidar.setPower(power);
    lidar.setObstacleStatus(obstacleStatus);
    return is;
}

std::ostream& operator<<(std::ostream& os, const Gyroscope& gyro) {
    os << gyro.getModel() << "|";
    os << gyro.getManufacturer();
    return os;
}

std::istream& operator>>(std::istream& is, Gyroscope& gyro) {
    std::string model, manufacturer;
    std::getline(is, model, '|');
    std::getline(is, manufacturer);
    
    gyro.setModel(model);
    gyro.setManufacturer(manufacturer);
    return is;
}

std::ostream& operator<<(std::ostream& os, const LCDScreen& lcd) {
    os << lcd.getSize() << "|";
    os << lcd.getModel();
    return os;
}

std::istream& operator>>(std::istream& is, LCDScreen& lcd) {
    std::string size, model;
    std::getline(is, size, '|');
    std::getline(is, model);
    
    lcd.setSize(size);
    lcd.setModel(model);
    return is;
}

std::ostream& operator<<(std::ostream& os, const Bettery& battery) {
    os << battery.getParams() << "|";
    os << battery.getOutputVolt() << "|";
    os << battery.getChargeTime();
    return os;
}

std::istream& operator>>(std::istream& is, Bettery& battery) {
    std::string params, outputVolt, chargeTime;
    std::getline(is, params, '|');
    std::getline(is, outputVolt, '|');
    std::getline(is, chargeTime);
    
    battery.setParams(params);
    battery.setOutputVolt(outputVolt);
    battery.setChargeTime(chargeTime);
    return is;
}

std::ostream& operator<<(std::ostream& os, const Student& student) {
    os << student.getId() << "|";
    os << student.getName();
    return os;
}

std::istream& operator>>(std::istream& is, Student& student) {
    std::string id, name;
    std::getline(is, id, '|');
    std::getline(is, name);
    
    student.setId(id);
    student.setName(name);
    return is;
}

// Car类成员函数实现
void Car::initDefaultComponents() {
    chassis.setId("dp" + carId.substr(5, 13));
    chassis.setModel("SCOUT MINI");
    chassis.setWheelbase("451mm");
    chassis.setTrackWidth("490mm");
    chassis.setMinGroundClear("115mm");
    chassis.setMinTurnRadius("0mm");
    chassis.setDriveType("四驱四轮");
    chassis.setMaxRange("10km");
    for (int i = 0; i < 4; i++) {
        Tire tire;
        tire.setType("公路轮、麦克纳姆轮");
        tire.setSize("175mm");
        chassis.setTires(i, tire);
    }

    agxKit.setModel("AGX Xavier");
    agxKit.setAiPerformance("32 TOPS");
    agxKit.setCudaCores("512");
    agxKit.setTensorCores("64");
    agxKit.setVram("32G");
    agxKit.setStorage("32G");

    stereoCamera.setModel("RealSense D4351");
    stereoCamera.setCamModule("D430");
    stereoCamera.setRgbRes("1920x1080");
    stereoCamera.setRgbFps("30");
    stereoCamera.setFov("87*58");
    stereoCamera.setDepthFps("90");

    lidar.setModel("RS-Helios-16p");
    lidar.setLines("16");
    lidar.setTestRange("100m");
    lidar.setPower("8W");

    gyroscope.setModel("CH110");
    gyroscope.setManufacturer("NXP");

    lcdScreen.setSize("11.6");
    lcdScreen.setModel("super");

    bettery.setParams("24V/15Ah");
    bettery.setOutputVolt("24V");
    bettery.setChargeTime("2H");
}

Car::Car() : carId("dp00000000") {
    initDefaultComponents();
}

Car::Car(const std::string& carId) : carId(carId) {
    initDefaultComponents();
}

void Car::setCarId(const std::string& carId) {
    if (carId.substr(0, 5) == "cqusn" && carId.length() == 16) {
        this->carId = carId;
        this->chassis.setId("dp" + carId.substr(5, 13));
        std::cout << "小车编号设置成功" << std::endl;
    } else {
        std::cerr << "小车编号格式错误（需cqusn打头16位）" << std::endl;
    }
}

void Car::assignStudent(const Student& student) {
    this->student = student;
    this->isAssignedStudent = true;
    std::cout << "学生分配成功" << std::endl;
}

void Car::setChassis(const Chassis& chassis) {
    this->chassis = chassis;
    std::cout << "底盘信息设置成功" << std::endl;
}

void Car::setAGXKit(const AGXKit& agxKit) {
    this->agxKit = agxKit;
    std::cout << "AGX套件信息设置成功" << std::endl;
}

void Car::setStereoCamera(const StereoCamera& stereoCamera) {
    this->stereoCamera = stereoCamera;
    std::cout << "双目摄像头信息设置成功" << std::endl;
}

void Car::setLiDAR(const LiDAR& lidar) {
    this->lidar = lidar;
    std::cout << "多线激光雷达信息设置成功" << std::endl;
}

void Car::setGyroscope(const Gyroscope& gyroscope) {
    this->gyroscope = gyroscope;
    std::cout << "9轴陀螺仪信息设置成功" << std::endl;
}

void Car::setLCDScreen(const LCDScreen& lcdScreen) {
    this->lcdScreen = lcdScreen;
    std::cout << "液晶显示屏信息设置成功" << std::endl;
}

void Car::setBattery(const Bettery& bettery) {
    this->bettery = bettery;
    std::cout << "电池信息设置成功" << std::endl;
}

bool Car::getIsAssignedStudent() const {
    return isAssignedStudent;
}

std::string Car::getCarId() const {
    return carId;
}

Student Car::getStudent() const {
    return student;
}

// 关键修复：实现非const和const版本的getter
Chassis& Car::getChassis() {
    return chassis;
}
const Chassis& Car::getChassis() const {
    return chassis;
}

AGXKit Car::getAGXKit() const {
    return agxKit;
}

StereoCamera Car::getStereoCamera() const {
    return stereoCamera;
}

LiDAR& Car::getLiDAR() {
    return lidar;
}
const LiDAR& Car::getLiDAR() const {
    return lidar;
}

Gyroscope Car::getGyroscope() const {
    return gyroscope;
}

LCDScreen Car::getLCDScreen() const {
    return lcdScreen;
}

Bettery Car::getBettery() const {
    return bettery;
}

void Car::displayCarInfo() const {
    std::cout << "-----------------小车信息-----------------" << std::endl;
    std::cout << "小车编号：" << getCarId() << std::endl;
    if (getIsAssignedStudent()) {
        std::cout << "分配学生：" << getStudent().getName() << "(" << getStudent().getId() << ")" << std::endl;
    } else {
        std::cout << "分配学生：未分配" << std::endl;
    }

    std::cout << "\n-----------------底盘信息-----------------" << std::endl;
    const Chassis& ch = getChassis();  // 调用const版本getter
    std::cout << "底盘编号：" << ch.getId() << std::endl;
    std::cout << "型号：" << ch.getModel() << std::endl;
    std::cout << "轴距：" << ch.getWheelbase() << std::endl;
    std::cout << "轮距：" << ch.getTrackWidth() << std::endl;
    std::cout << "最小离地间隙：" << ch.getMinGroundClear() << std::endl;
    std::cout << "最小转弯半径：" << ch.getMinTurnRadius() << std::endl;
    std::cout << "驱动类型：" << ch.getDriveType() << std::endl;
    std::cout << "最大行程：" << ch.getMaxRange() << std::endl;
    for (int i = 0; i < 4; ++i) {
        Tire tire = ch.getTires(i);
        std::cout << "轮胎" << i+1 << "：" << tire.getType() << "," << tire.getSize() << std::endl;
    }

    std::cout << "\n-----------------AGX套件信息-----------------" << std::endl;
    AGXKit agx = getAGXKit();
    std::cout << "型号：" << agx.getModel() << std::endl;
    std::cout << "AI性能：" << agx.getAiPerformance() << std::endl;
    std::cout << "CUDA核心数：" << agx.getCudaCores() << std::endl;
    std::cout << "Tensor核心数：" << agx.getTensorCores() << std::endl;
    std::cout << "显存：" << agx.getVram() << std::endl;
    std::cout << "储存：" << agx.getStorage() << std::endl;

    std::cout << "\n-----------------双目摄像头信息-----------------" << std::endl;
    StereoCamera cam = getStereoCamera();
    std::cout << "型号：" << cam.getModel() << std::endl;
    std::cout << "摄像头模块：" << cam.getCamModule() << std::endl;
    std::cout << "RGB分辨率：" << cam.getRgbRes() << std::endl;
    std::cout << "RGB帧率：" << cam.getRgbFps() << std::endl;
    std::cout << "视场角：" << cam.getFov() << std::endl;
    std::cout << "深度帧率：" << cam.getDepthFps() << std::endl;

    std::cout << "\n-----------------多线激光雷达信息-----------------" << std::endl;
    const LiDAR& ld = getLiDAR();  // 调用const版本getter
    std::cout << "型号：" << ld.getModel() << std::endl;
    std::cout << "通道数：" << ld.getLines() << std::endl;
    std::cout << "测试范围：" << ld.getTestRange() << std::endl;
    std::cout << "功耗：" << ld.getPower() << std::endl;

    std::cout << "\n-----------------9轴陀螺仪信息-----------------" << std::endl;
    Gyroscope gyro = getGyroscope();
    std::cout << "型号：" << gyro.getModel() << std::endl;
    std::cout << "厂家：" << gyro.getManufacturer() << std::endl;

    std::cout << "\n-----------------液晶显示屏信息-----------------" << std::endl;
    LCDScreen lcd = getLCDScreen();
    std::cout << "尺寸：" << lcd.getSize() << "英寸" << std::endl;
    std::cout << "型号：" << lcd.getModel() << std::endl;

    std::cout << "\n-----------------电池信息-----------------" << std::endl;
    Bettery bat = getBettery();
    std::cout << "参数：" << bat.getParams() << std::endl;
    std::cout << "对外供电：" << bat.getOutputVolt() << std::endl;
    std::cout << "充电时间：" << bat.getChargeTime() << std::endl;
}

void Car::serialize(std::ostream& os) const {
    os << chassis << "\n";
    os << agxKit << "\n";
    os << stereoCamera << "\n";
    os << lidar << "\n";
    os << gyroscope << "\n";
    os << lcdScreen << "\n";
    os << bettery << "\n";
    os << student << "\n";
    os << carId << "\n";
    os << isAssignedStudent << "\n";
}

void Car::deserialize(std::istream& is) {
    std::string line;

    std::getline(is, line);
    std::istringstream(line) >> chassis;

    std::getline(is, line);
    std::istringstream(line) >> agxKit;

    std::getline(is, line);
    std::istringstream(line) >> stereoCamera;

    std::getline(is, line);
    std::istringstream(line) >> lidar;

    std::getline(is, line);
    std::istringstream(line) >> gyroscope;

    std::getline(is, line);
    std::istringstream(line) >> lcdScreen;

    std::getline(is, line);
    std::istringstream(line) >> bettery;

    std::getline(is, line);
    std::istringstream(line) >> student;

    std::getline(is, carId);
    
    std::getline(is, line);
    isAssignedStudent = (line == "1");
}

bool Car::saveCarsToFile(const std::vector<Car>& cars, const std::string& filename) {
    std::ofstream file(filename, std::ios::out | std::ios::binary);
    if (!file.is_open()) {
        std::cerr << "无法打开文件：" << filename << std::endl;
        return false;
    }

    size_t carCount = cars.size();
    file.write(reinterpret_cast<const char*>(&carCount), sizeof(carCount));

    for (const auto& car : cars) {
        std::ostringstream oss;
        car.serialize(oss);
        std::string carData = oss.str();
        size_t dataLen = carData.size();

        file.write(reinterpret_cast<const char*>(&dataLen), sizeof(dataLen));
        file.write(carData.c_str(), dataLen);
    }

    file.close();
    return true;
}

bool Car::loadCarsFromFile(std::vector<Car>& cars, const std::string& filename) {
    std::ifstream file(filename, std::ios::in | std::ios::binary);
    if (!file.is_open()) {
        std::cerr << "无法打开文件：" << filename << std::endl;
        return false;
    }

    cars.clear();

    size_t carCount;
    file.read(reinterpret_cast<char*>(&carCount), sizeof(carCount));

    for (size_t i = 0; i < carCount; ++i) {
        size_t dataLen;
        file.read(reinterpret_cast<char*>(&dataLen), sizeof(dataLen));

        std::string carData(dataLen, '\0');
        file.read(&carData[0], dataLen);

        Car car;
        std::istringstream iss(carData);
        car.deserialize(iss);

        cars.push_back(car);
    }

    file.close();
    return true;
}